package com.ydj.framework.filter;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.ydj.framework.exception.CommonException;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@Slf4j
public class ExtHttpServletResponse extends HttpServletResponseWrapper {

	private ByteArrayOutputStream output;
	private ServletOutputStream filterOutput;

	private final static String CONTENT_TYPE_TEXT_PLAIN = "text/plain;charset=UTF-8";
	private final static String CONTENT_TYPE_EXCEL = "application/vnd.ms-excel;charset=utf-8";
	private final static String CONTENT_TYPE_EXCEL_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
	public final static String CONTENT_TYPE_JPEG = "image/jpeg";
	public final static String CONTENT_TYPE_JSON = "application/json";

	@Setter
	private boolean outputFileFlag = false;

	public ExtHttpServletResponse(HttpServletResponse response) {
		super(response);
		response.setHeader("Content-type", CONTENT_TYPE_JSON);
		response.setCharacterEncoding("UTF-8");
		output = new ByteArrayOutputStream();
	}

	public void configEasyExcelHeader(String fileName) throws IOException {
		outputFileFlag = true;
		setContentType(CONTENT_TYPE_EXCEL_XLSX);
		setCharacterEncoding("utf-8");
		String outFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
		setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + outFileName);
	}

	public void outputXml(String xml) throws IOException {
		setContentType("text/xml");
		getWriter().print(xml);
	}

	public void outputJpeg(byte[] image) throws IOException {
		outputFileFlag = true;
		setContentType(CONTENT_TYPE_JPEG);
		ServletOutputStream os = getOutputStream();
		os.write(image);
		os.flush();
	}

	@Override
	public ServletOutputStream getOutputStream() {
		if (filterOutput == null) {
			filterOutput = new ServletOutputStream() {
				@Override
				public void write(int b) {
					output.write(b);
				}

				@Override
				public boolean isReady() {
					return false;
				}

				@Override
				public void setWriteListener(WriteListener writeListener) {
				}
			};
		}
		return filterOutput;
	}

	public String getResponseDataToPrintLog() {
		if (outputFileFlag) {
			return "返回的是文件，大小为" + output.size();
		}

		return new String(output.toByteArray(), StandardCharsets.UTF_8);
	}

	public void outputToClient() throws IOException {
		if (outputFileFlag) {
			super.getOutputStream().write(output.toByteArray());
			return;
		}

		getWriter().print(getResponseDataToPrintLog());
	}

	/**
	 *
	 * @param rowData
	 * @param excelFileName     会员列表导出.xlsx
	 * @param templateResPath   template.excel/VipListTemplate.xlsx
	 */
	public void outputExcel(List<?> rowData, Map<String, Object> mapData, String excelFileName, String templateResPath) throws IOException, CommonException {
		this.configEasyExcelHeader(excelFileName);

		// 现在把数据写入excel了
		Resource resource = new ClassPathResource(templateResPath);
		try (InputStream inputStream = resource.getInputStream()) {
			ExcelWriter excelWriter = EasyExcel.write(this.getOutputStream())
					.withTemplate(inputStream)
					.autoTrim(true)
					.excelType(ExcelTypeEnum.XLSX)
					.build();

			WriteSheet writeSheet = EasyExcel.writerSheet().build();
			if (rowData != null) {
				FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
				excelWriter.fill(rowData, fillConfig, writeSheet);
			}
			if (mapData != null) {
				excelWriter.fill(mapData, writeSheet);
			}
			excelWriter.finish();

		} catch (Exception e) {
			CommonException.throwException("导出Excel失败，请联系系统管理员");
			log.error("导出Excel失败，请联系系统管理员", e);
		}
	}
}